<?php

/*
	File: mvc.php
	Date: 01/09/2009
	Description:
	mvc.php is a mini-MVC framework
	- views are stored in "views/" directory
	- controller and actions are dispatched by Dispatch class
		thankful to information contained in IControllerRequest implemented object
*/
if (!class_exists('MagicObject')) require_once 'MagicObject.php';

interface IControllerRequest {
	/*
	 * Get a action from request
	 * @return string
	 */
	function getAction();
	
	/*
	 * Get a params from request
	 * @return ArrayObject
	 */
	function getParams();
	
	/*
	 * Get a controller from request
	 * @return Controller
	 */
	function getController();
}

/*
	This class encapsulate HTML file views.
	Its methods are accessible from HTML views.
*/
class View extends MagicObject {
	/*
	 * @argument $view string view_name corresponding to a "views/view_name.html"
	 * @argument $this_object Controller|View parent object used to access parent variables
	 */
	public function __construct ($view, $this_object = null) {
		parent::__construct($this_object);
		$this->view = $view;
		include('views/'. $this->view. '.html');
	}
	
	/*
	 * Include a subview by calling View constructor
	 * @argument $view string view_name corresponding to a "views/view_name.html"
	 * @argument $this_object Controller|View parent object used to access parent variables
	 */
	public function include_view ($view, $this_object = null) {
		new View($view, $this_object);
	}
}

/*
	To use a controller, you must extends this object.
	Methods defined in the subclass class are called by Dispatch class ase Request actions
*/
abstract class Controller {
	public function __construct ($params) {
		$this->params = $params;
		$this->initialize();
	}
	
	public function initialize () {}
	
	/*
	 * Perform controller action
	 * @argument $name string action_name
	 */
	public function call ($action) {
		// action name is used as view name by default
		$this->view = $action;
		$this->$action();
		
		// if view is setted, perform include
		if ($this->view)
			$this->include_view($this->view, $this);
	}
	
	private function include_view ($view, $this_object) {
		new View($view, $this_object);
	}
}

class Dispatcher {
	static function dispatch (IControllerRequest $request) {
		$controller = $request->getController();
		$controller->call($request->getAction());
	}
}

?>